#include "Logger.h"
#include <sstream>
#include <iomanip>

// 初始化静态成员
LogLevel Logger::currentLevel = INFO;
std::ofstream Logger::logFile;
std::mutex Logger::logMutex;

// 获取单例实例
Logger& Logger::getInstance() {
    static Logger instance;
    return instance;
}

// 构造函数
Logger::Logger() 
    : currentLevel(INFO), 
      consoleOutput(true), 
      fileOutput(false), 
      logFilename("gb_client.log") {
}

// 设置日志级别
void Logger::setLogLevel(LogLevel level) {
    currentLevel = level;
}

// 获取当前日志级别
LogLevel Logger::getLogLevel() const {
    return currentLevel;
}

// 设置是否输出到控制台
void Logger::setConsoleOutput(bool enabled) {
    consoleOutput = enabled;
}

// 设置是否输出到文件
void Logger::setFileOutput(bool enabled, const std::string& filename) {
    std::lock_guard<std::mutex> lock(logMutex);
    
    if (fileOutput && logFile.is_open()) {
        logFile.close();
    }
    
    fileOutput = enabled;
    
    if (enabled) {
        logFilename = filename;
        logFile.open(logFilename, std::ios::app);
        if (!logFile.is_open()) {
            std::cerr << "无法打开日志文件: " << logFilename << std::endl;
            fileOutput = false;
        }
    }
}

// 记录日志的主要方法
void Logger::log(LogLevel level, const std::string& file, int line, const std::string& function, const std::string& message) {
    if (level < currentLevel) {
        return;
    }
    
    std::string timestamp = getCurrentTimeString();
    std::string levelStr = getLevelString(level);
    
    // 构建日志消息
    std::ostringstream logStream;
    logStream << timestamp << " ";
    
    // 对于DEBUG及以上级别，添加文件和行号信息
    if (level <= DEBUG) {
        logStream << "[" << levelStr << " " << file << ":" << line << " " << function << "] ";
    } else {
        logStream << "[" << levelStr << "] ";
    }
    
    logStream << message;
    std::string logMessage = logStream.str();
    
    // 输出到控制台
    if (consoleOutput) {
        std::lock_guard<std::mutex> lock(logMutex);
        std::cout << logMessage << std::endl;
    }
    
    // 输出到文件
    if (fileOutput && logFile.is_open()) {
        std::lock_guard<std::mutex> lock(logMutex);
        logFile << logMessage << std::endl;
        logFile.flush();
    }
}

// 获取日志级别的字符串表示
std::string Logger::getLevelString(LogLevel level) {
    switch (level) {
        case TRACE: return "TRACE";
        case DEBUG: return "DEBUG";
        case INFO:  return "INFO ";
        case WARN:  return "WARN ";
        case ERROR: return "ERROR";
        case FATAL: return "FATAL";
        default:    return "UNKN ";
    }
}

// 获取当前时间的字符串表示
std::string Logger::getCurrentTimeString() {
    auto now = std::chrono::system_clock::now();
    auto now_c = std::chrono::system_clock::to_time_t(now);
    
    // 获取毫秒
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
    
    std::ostringstream oss;
    std::tm tm_buf;
    
#ifdef _WIN32
    localtime_s(&tm_buf, &now_c);
#else
    localtime_r(&now_c, &tm_buf);
#endif
    
    oss << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S");
    oss << '.' << std::setfill('0') << std::setw(3) << ms.count();
    
    return oss.str();
} 